package com.fi.recogn.util;

import fr.opensagres.poi.xwpf.converter.xhtml.Base64EmbedImgManager;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Entities;
import org.w3c.tidy.Tidy;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * @Description TODO 文件转化工具类
 * @Author lujiahong
 * @Date 2024/8/13 14:06
 */
public class FileConvertUtil {

    /**
     * @desc TODO doc转docx
     *
     * @param document org.apache.poi.hwpf.HWPFDocument
     * @return org.apache.poi.xwpf.usermodel.XWPFDocument
     * @author lujiahong
     * @date 2024/08/13 14:23
     */
    public static XWPFDocument docConvertDocx(HWPFDocument document){
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            org.w3c.dom.Document htmlDocument = factory.newDocumentBuilder().newDocument();
            WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(htmlDocument);
            wordToHtmlConverter.processDocument(document);

            ByteArrayOutputStream htmlOutputStream = new ByteArrayOutputStream();
            DOMSource domSource = new DOMSource(htmlDocument);
            StreamResult streamResult = new StreamResult(htmlOutputStream);

            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();
            serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty(OutputKeys.METHOD, "html");
            serializer.transform(domSource, streamResult);

            htmlOutputStream.close();

            // 使用 Jsoup 清理 HTML
            String htmlContent = new String(htmlOutputStream.toByteArray(), "UTF-8");
            Document jsoupDoc = Jsoup.parse(htmlContent);
            jsoupDoc.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
            jsoupDoc.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
            String cleanedHtmlContent = jsoupDoc.html();

            // 使用 Docx4j 将清理后的 HTML 转换为 DOCX
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
            XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackage);
            wordMLPackage.getMainDocumentPart().getContent().addAll(xhtmlImporter.convert(cleanedHtmlContent, null));

            return convertToXWPFDocument(wordMLPackage);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("doc转docx失败");
        }
    }
    public static XWPFDocument convertToXWPFDocument(WordprocessingMLPackage wordMLPackage) throws Exception {
        // 将 WordprocessingMLPackage 序列化为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        wordMLPackage.save(baos);
        baos.close();

        // 从字节数组创建 XWPFDocument
        return new XWPFDocument(new ByteArrayInputStream(baos.toByteArray()));
    }

    /**
     * @desc TODO rtf转docx
     *
     * @param is trf文件输入流
     * @return org.apache.poi.xwpf.usermodel.XWPFDocument
     * @author lujiahong
     * @date 2024/08/30 11:46
     */
    public static XWPFDocument rtfConvertDocx(InputStream is) {
        try {
            // 加载RTF文件
            com.aspose.words.Document doc = new com.aspose.words.Document(is);
            // 保存到输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            doc.save(baos, com.aspose.words.SaveFormat.DOCX);
            byte[] bytes = baos.toByteArray();
            // 转为输入流
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            // 转为XWPFDocument
            return new XWPFDocument(bais);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("rtf转docx失败");
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @desc TODO rtf转doc
     *
     * @param is trf文件输入流
     * @return org.apache.poi.hwpf.HWPFDocument
     * @author lujiahong
     * @date 2024/08/30 11:46
     */
    public static HWPFDocument rtfConvertDoc(InputStream is) {
        try {
            // 加载RTF文件
            com.aspose.words.Document doc = new com.aspose.words.Document(is);
            // 保存到输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            doc.save(baos, com.aspose.words.SaveFormat.DOC);
            byte[] bytes = baos.toByteArray();
            // 转为输入流
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            // 转为XWPFDocument
            return new HWPFDocument(bais);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("rtf转doc失败");
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * @desc TODO docx转html
     *
     * @param hwpfDocument org.apache.poi.hwpf.HWPFDocument
     * @return java.lang.String
     * @author lujiahong
     * @date 2024/08/15 17:03
     */
    public static String docToHtml(HWPFDocument hwpfDocument) {
        //doc文件使用HWPFDocument读取，docx文件使用XWPFDocument读取
        try {
            WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                    DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());//构造WordToHtmlConverter对象

            //开始解析doc文档---------------------------------------------
            wordToHtmlConverter.processDocument(hwpfDocument);
            org.w3c.dom.Document document = wordToHtmlConverter.getDocument();
            //通过TransformerFactory创造出Transformer ,并设置Transformer的属性
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT,"yes");
            transformer.setOutputProperty(OutputKeys.METHOD,"html");

            //transformer.transform()需要参数1 Source 参数2 Result
            DOMSource domSource = new DOMSource(document);
            ByteArrayOutputStream outputtarget = new ByteArrayOutputStream();
            StreamResult streamResult = new StreamResult(outputtarget);
            //开始转换,结果数据在ByteArrayOutputStream里
            transformer.transform(domSource,streamResult);//参数1 Source 参数2 Result

            //转成字符串看看
            String string = outputtarget.toString("utf-8");
            outputtarget.close();
            return string;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("doc转html失败");
        }
    }

    /**
     * @desc TODO docx转html
     *
     * @param xwpfDocument org.apache.poi.xwpf.usermodel.XWPFDocument
     * @return java.lang.String
     * @author lujiahong
     * @date 2024/08/15 17:04
     */
    public static String docxToHtml(XWPFDocument xwpfDocument) {
        try {
            //解析XHTML配置
            XHTMLOptions xhtmlOptions = XHTMLOptions.create();
            // 将样式都写为内联样式，而不是写到style标签中 默认false
            xhtmlOptions.setFragment(true);
            xhtmlOptions.setIgnoreStylesIfUnused(false);
            xhtmlOptions.setImageManager(new Base64EmbedImgManager());//图片用base64转化

            //将XWPFDocument转化成HTML
            ByteArrayOutputStream outputtarget = new ByteArrayOutputStream();
            XHTMLConverter.getInstance().convert(xwpfDocument,outputtarget,xhtmlOptions);

            //转成字符串看看
            String string = outputtarget.toString("utf-8");
            outputtarget.close();
            return string;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("docx转html失败");
        }
    }
}